package com.tyut.musicdreamer.framework.starter.web.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.tyut.musicdreamer.framework.starter.web.advice.GlobalExceptionHandlerAdvice;
import com.tyut.musicdreamer.framework.starter.web.advice.GlobalResponseBodyAdvice;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import java.io.IOException;

/**
 * Web 组件自动装配
 */
@Configuration
@ComponentScan(basePackages = {"com.tyut.musicdreamer.framework.starter.web"})
public class WebAutoConfiguration {
    
    /**
     * 创建ObjectMapper Bean
     * 用于JSON序列化和反序列化
     */
    @Bean
    @Primary
    @ConditionalOnMissingBean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        
        // 设置序列化和反序列化特性
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        
        // 注册Java 8日期时间模块
        objectMapper.registerModule(new JavaTimeModule());
        
        // 添加自定义模块以将大整数(Long)序列化为字符串，避免JS精度丢失问题
        SimpleModule longToStringModule = new SimpleModule();
        longToStringModule.addSerializer(Long.class, new JsonSerializer<Long>() {
            @Override
            public void serialize(Long value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
                jsonGenerator.writeString(value.toString());
            }
        });
        longToStringModule.addSerializer(long.class, new JsonSerializer<Long>() {
            @Override
            public void serialize(Long value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
                jsonGenerator.writeString(value.toString());
            }
        });
        objectMapper.registerModule(longToStringModule);
        
        return objectMapper;
    }
    
    @Bean
    @ConditionalOnMissingBean
    public GlobalExceptionHandlerAdvice globalExceptionHandler() {
        return new GlobalExceptionHandlerAdvice();
    }

    @Bean
    @ConditionalOnMissingBean
    public GlobalResponseBodyAdvice globalResponseBodyAdvice() {
        return new GlobalResponseBodyAdvice();
    }

}
